/** @jsxRuntime automatic */
/** @jsxImportSource ../xml-runtime */
import { create } from 'xmlbuilder2'
import { render } from '../xml-runtime/shared'
import { getFramePairs } from 'auto-cut-video-lib/Frame'
import { getMultiple, getStdFrameRate } from 'auto-cut-video-lib/FCP'

import { Sequence } from './Sequence'
import { Resources } from './Resources'

function getResources(pathObject, mediaInfo, sequenceInfo) {
  if (mediaInfo.width) {
    return (
      <Resources.Video
        pathObject={pathObject}
        mediaInfo={mediaInfo}
        sequenceInfo={sequenceInfo}
      ></Resources.Video>
    )
  } else {
    return (
      <Resources.Audio
        pathObject={pathObject}
        mediaInfo={mediaInfo}
        sequenceInfo={sequenceInfo}
      ></Resources.Audio>
    )
  }
}

export function generateXML(pathObject, mediaInfo, secPairs) {
  // vlevin @ 2022-11-05 这个倍数计算的基础是sequence的帧率而非media的帧率
  const sequenceFrameRate = getStdFrameRate(mediaInfo.frameRate)
  const sequenceMultiple = getMultiple(sequenceFrameRate)

  // vlevin @ 2022-11-05 媒体倍数，只用于音频resource.asset.duration的值
  // vlevin @ 2022-11-05 而且计算基础是音频的时长，因为帧率一定是整数
  const mediaMultiple = getMultiple(mediaInfo.duration)

  // vlevin @ 2022-06-29 计算剪辑点，以frame表示，顺便计算sequence总时长
  const framePairs = getFramePairs(
    secPairs,
    sequenceFrameRate,
    sequenceMultiple
  )
  const clipItems = []
  let offset = 0
  for (const framePair of framePairs) {
    const duration = framePair[1] - framePair[0]
    clipItems.push({
      offset,
      start: framePair[0],
      duration,
    })
    offset += duration
  }
  const sequenceInfo = {
    frameCount: offset,
    frameRate: sequenceFrameRate,
    multiple: sequenceMultiple,
  }

  // vlevin @ 2022-06-29 生成xml字符串
  const container = create({ encoding: 'UTF-8' }).dtd({ name: 'fcpxml' })
  render(
    <fcpxml version="1.10">
      {getResources(
        pathObject,
        { ...mediaInfo, multiple: mediaMultiple },
        sequenceInfo
      )}
      <Sequence
        pathObject={pathObject}
        mediaInfo={mediaInfo}
        clipItems={clipItems}
        sequenceInfo={sequenceInfo}
      ></Sequence>
    </fcpxml>,
    container
  )
  let xmlString = container.end()

  return xmlString
}
